/**
 * Copyright (c) 2020-2021 ThunderSoft
 * All Rights Reserved by Thunder Software Technology Co., Ltd and its affiliates.
 * You may not use, copy, distribute, modify, transmit in any form this file
 * except in compliance with ThunderSoft in writing by applicable law.
 *
 */
/**
 * @file    hal_ble.c
 * @brief   hal ble funtion 
 * @details hal ble funtion
 * @version 1.0
 * @author  Hu lei
 * @date    2021-03-05
 *
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                     NAME               DESCRIPTION
 * 2021-03-05               Hu lei              Create it.
 *
 */
#include "turbox_ble.h"
#include "ohos_bt_gatt.h"
#include "ohos_bt_gatt_client.h"
#include "ohos_bt_gatt_server.h"
#include "hci_host.h"
#include "conn.h"
#include "hci_core.h"
#include "smp.h"
#include "gatt.h"
#include "uuid.h"
#include <stdlib.h>

#define BT_RET_OK  (0)
#define BT_RET_NG  (-1)

#define IND_ARRAY_SIZE 6
enum{
    HAL_GATT_IND_IDLE = 0,
    HAL_GATT_IND_BUSY
};

#define START_ADV_ALREADY   (1)
#define START_ADV_NONE      (0)

static unsigned char startAdvFlag = START_ADV_NONE;
struct GattIndicateBuf{
    int serverId;
    GattsSendIndParam *param;
};

struct GattIndicateBuf *indBufArray;
struct GattIndicateEnv{ 
    struct k_queue ind_queue;
    uint8_t ind_state;
};

static struct GattIndicateEnv indicate_env;
// volatile char g_flag = 1;
BtGattCallbacks *gapcb;
BtGattServerCallbacks *gattscb;
static void ble_connected(int connId, int serverId, const bt_addr_le_t *bdaddr);
static void ble_disconnected(int connId, int serverId, const bt_addr_le_t *bdaddr);
static void ble_gatt_mtu_changed_cb(int connId, int mtu);
static void ble_hal_ind_confirm_cb(int connId, int status);


static hal_gatt_server_cb_t halgattcb = {
    .connected = ble_connected,
    .disconnected = ble_disconnected,
    .mtu_changed_cb = ble_gatt_mtu_changed_cb,
    .ind_confirm_cb = ble_hal_ind_confirm_cb,
};

static void ble_connected(int connId, int serverId, const bt_addr_le_t *bdaddr)
{
    BdAddr dst_addr;
    (void)dst_addr;

    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("connId = %d, serverId = %d, bdaddr = %p \r\n", connId, serverId, bdaddr);
    if (NULL == bdaddr) {
        printf("Input bdaddr is NULL \r\n");
        return;
    }

    if(gattscb && gattscb->connectServerCb) {
        memcpy(dst_addr.addr, bdaddr->a.val, OHOS_BD_ADDR_LEN);
        (gattscb->connectServerCb)(connId, 0, &dst_addr);
        printf("ConnectServerCallback function call \r\n");
    } else {
        printf("gattscb/gattscb->connectServerCb is NULL\r\n");
    }
    
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
}

static void ble_disconnected(int connId, int serverId, const bt_addr_le_t *bdaddr)
{
    BdAddr dst_addr;
    (void)dst_addr;
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);

    printf("connId:%d--serverId:%d--bdaddr:%p\r\n", connId, serverId, bdaddr);
    if (NULL == bdaddr) {
        printf("bdaddr is NULL\r\n");
        return;
    }

    if(gattscb && gattscb->disconnectServerCb) {
        memcpy(dst_addr.addr, bdaddr->a.val, OHOS_BD_ADDR_LEN);
        (gattscb->disconnectServerCb)(connId, 0, &dst_addr);
        printf("DisconnectServerCallback function call \r\n");
    } else {
        printf("gattscb/gattscb->disconnectServerCb is NULL \r\n");
    }
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
}

static void ble_gatt_mtu_changed_cb(int connId, int mtu) {
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("connId:%d--mtu:%d\r\n", connId, mtu);
    if (gattscb && gattscb->mtuChangeCb) {
        (gattscb->mtuChangeCb)(connId, mtu);
        printf("MtuChangeCallback function call \r\n");
    } else {
        printf("gattscb/gattscb->mtuChangeCb is NULL\r\n");
    }
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
}

static void ble_hal_ind_confirm_cb(int connId, int status)
{
    struct GattIndicateBuf *ind;
    (void)(ind);
    printf("%s Received indicate confirm!!! \r\n", __FUNCTION__);
    indicate_env.ind_state = HAL_GATT_IND_IDLE;

    if(gattscb && gattscb->indicationSentCb)
    {
        (gattscb->indicationSentCb)(0, status);
        printf("IndicationSentCallback call \r\n");
    } else {
        printf("gattscb && gattscb->indicationSentCb is NULL\r\n");
    }
  
    if(k_queue_is_empty(&indicate_env.ind_queue))
        return;

    ind = k_fifo_get(&indicate_env.ind_queue, K_NO_WAIT);

    printf("%s send gatt indication from buffer list\r\n", __FUNCTION__);
    if(ind){
        BleGattsSendIndication(ind->serverId, ind->param);
        if(ind->param){
            free(ind->param->value);
            ind->param->value = NULL;
        }
        free(ind->param);
        ind->param = NULL;
    }
}

void BleSecRespCb(bt_addr_le_t *bdaddr)
{
    BdAddr dst_addr;
    (void)dst_addr;
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);

    if (NULL == bdaddr) {
        printf("bdaddr is NULL\r\n");
        return;
    }
    
    if (gapcb && gapcb->securityRespondCb) {
        memcpy(dst_addr.addr, bdaddr->a.val, OHOS_BD_ADDR_LEN);
        (gapcb->securityRespondCb)(&dst_addr);
        printf("SecurityRespondCallback call \r\n");
    } else {
        printf("gapcb/gapcb->securityRespondCb is NULL!!! \r\n");
    }
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
}

int ble_push_indicate_info(int serverId, GattsSendIndParam *param)
{
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    for(int i=0; i < IND_ARRAY_SIZE; i++)
    {
        if(indBufArray[i].param == NULL)
        {
            indBufArray[i].serverId = serverId;
            indBufArray[i].param = (GattsSendIndParam *)malloc(sizeof(GattsSendIndParam));
            if(!indBufArray[i].param)
            {
                printf("%s Fail to allocate memory!!! \r\n", __FUNCTION__);
                return BT_RET_NG;
            }
            memcpy(indBufArray[i].param, param, sizeof(GattsSendIndParam));
            
            indBufArray[i].param->value = malloc(param->valueLen);
            
            if(!indBufArray[i].param->value)
             {
                printf("%s Fail to allocate memory!!! \r\n", __FUNCTION__);
                return BT_RET_NG;
            }
            
            memcpy(indBufArray[i].param->value, param->value, param->valueLen);
            
            k_fifo_put(&indicate_env.ind_queue, &indBufArray[i]);
            
            return BT_RET_OK;
        }
    }

    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
    return BT_RET_NG;
}

/*************************************************************
*Need to adapter interface
**************************************************************/
/**
 * Initialize the bt stack
 * 
 * it must call InitBtStack -> EnableBtStack if want to use ble
 **/
int InitBtStack(void) {
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    indBufArray = malloc(sizeof(struct GattIndicateBuf) * IND_ARRAY_SIZE);
    if(!indBufArray)
    {
        printf("%s Fail to allocate buffer for indBufArray\r\n", __FUNCTION__);
        return BT_RET_NG;
    }
    memset(indBufArray, 0 , sizeof(struct GattIndicateBuf) * IND_ARRAY_SIZE);
    k_queue_init(&indicate_env.ind_queue, IND_ARRAY_SIZE);
    indicate_env.ind_state = HAL_GATT_IND_IDLE;
    hal_init_ble_stack(&halgattcb);
    hal_ble_auth(BleSecRespCb);
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
    return BT_RET_OK;
}

/**
 * enable bt stack
 * 
 * it must call InitBtStack -> EnableBtStack if want to use ble
 **/
int EnableBtStack(void) {
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    if (BT_RET_OK == hal_enable_ble()) {
        printf("enable bt stack OK\r\n");
        printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
        return BT_RET_OK;
    } else {
        printf("enable bt stack NG\r\n");
        printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
        return BT_RET_NG;
    }
}

/**
 * disable the ble
 **/
int DisableBtStack(void) {
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    if(indBufArray)
        free(indBufArray);
    k_queue_free(&indicate_env.ind_queue);
    if (BT_RET_OK == hal_ble_disable()) {
        printf("disable bt stack OK\r\n");
        printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
        return BT_RET_OK;
    } else {
        printf("disable bt stack NG\r\n");
        printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
        return BT_RET_NG;
    }
}

/**
 * call Original factory interface
 **/
int SetDeviceName(const char *name, unsigned int len) {
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("deviceName:%s--len:%d\r\n", name, (int)(len));
    if (BT_RET_OK == hal_ble_set_device_name(name, len)) {
        printf("Set Device Name OK\r\n");
        printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
        return BT_RET_OK;
    } else {
        printf("Set Device Name NG\r\n");
        printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
        return BT_RET_NG;
    }
}

extern int set_ad_and_rsp_d(u16_t hci_op, u8_t *data, u32_t ad_len);
/**
 * do not understand how to use the advId Parameter
 **/
int BleSetAdvData(int advId, const BleConfigAdvData *data) {
    int ret = 0;
    (void)(advId);
    unsigned char *advData = NULL;
    unsigned char *scanRspData = NULL;
    unsigned int advLength = 0;
    unsigned int scanRspLength = 0;
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("advId:%d--data:%p\r\n", advId, data);
    if (NULL == data) {
        printf("BleSetAdvData Entry!data is NULL\r\n");
        return BT_RET_NG;
    }

    advLength = (unsigned int)(data->advLength);
    advData = (unsigned char *)(data->advData);
    scanRspLength = (unsigned int)(data->scanRspLength);
    scanRspData = (unsigned char *)(data->scanRspData);

    printf("advLength:%d--scanRspLength:%d\r\n", (int)(advLength), (int)(advData));

    // set data to BT_HCI_OP_LE_SET_ADV_DATA
    ret = set_ad_and_rsp_d(BT_HCI_OP_LE_SET_ADV_DATA, advData, advLength);
    if (BT_RET_OK != ret) {
        printf("set data to BT_HCI_OP_LE_SET_ADV_DATA NG; reason:%d\r\n", ret);
        return BT_RET_NG;
    } else {
        printf("set data to BT_HCI_OP_LE_SET_ADV_DATA OK\r\n");
    }

    // set data to BT_HCI_OP_LE_SET_SCAN_RSP_DATA
    ret = set_ad_and_rsp_d(BT_HCI_OP_LE_SET_SCAN_RSP_DATA, scanRspData, scanRspLength);
    if (BT_RET_OK != ret) {
        printf("set data to BT_HCI_OP_LE_SET_SCAN_RSP_DATA NG; reason:%d\r\n", ret);
        ret = BT_RET_NG;
    } else {
        printf("set data to BT_HCI_OP_LE_SET_SCAN_RSP_DATA OK\r\n");
    }
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);

    return ret;
}


int BleStartAdv(int advId, const BleAdvParams *param) {
    int ret = 0;
    unsigned char mode = 0;
    unsigned char adv_type = 0xff;
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("advId:%d---param:%p\r\n", advId, param);
    if (NULL == param) {
        printf("param is NULL\r\n");
    }

    // Get adv type, 0:adv_ind,  1:adv_scan_ind, 2:adv_nonconn_ind 3: adv_direct_ind
    printf("advType is %d\r\n", param->advType);
    switch (param->advType) {
        case OHOS_BLE_ADV_IND:
            adv_type = 0;
            break;

        case OHOS_BLE_ADV_SCAN_IND:
            adv_type = 1;
            break;

        case OHOS_BLE_ADV_NONCONN_IND:
            adv_type = 2;
            break;

        case OHOS_BLE_ADV_DIRECT_IND_HIGH:
        case OHOS_BLE_ADV_DIRECT_IND_LOW:
            adv_type = 3;
            break;

        default:
            printf("advType is invalid\r\n");
            return BT_RET_NG;
    }

    printf("advFilterPolicy is %d\r\n", param->advFilterPolicy);
    switch (param->advFilterPolicy) {
        case OHOS_BLE_ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY:
        case OHOS_BLE_ADV_FILTER_ALLOW_SCAN_ANY_CON_WLST:
            adv_type = 0;
            break;

        case OHOS_BLE_ADV_FILTER_ALLOW_SCAN_WLST_CON_ANY:
        case OHOS_BLE_ADV_FILTER_ALLOW_SCAN_WLST_CON_WLST:
            adv_type = 2;
            break;

        default:
            printf("advFilterPolicy is invalid\r\n");
            return BT_RET_NG;
    }
    /* mode : 0:General discoverable*/
    ret = hal_ble_start_advertise(advId, adv_type, 0, param->minInterval, param->maxInterval);
    if (BT_RET_OK != ret) {
        printf("start ble advertise NG; reason:%d\r\n", ret);
        ret = BT_RET_NG;
    } else {
        printf("start ble advertise OK\r\n");
    }

    if(gapcb && gapcb->advEnableCb) {
        gapcb->advEnableCb(advId, ret);
        printf("AdvEnableCallback function call \r\n");
    } else {
        printf("gapcb/gapcb->advEnableCb is NULL\r\n");
    }
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
    
    return ret;
}

/**
 * stop ble advertise
 **/
int BleStopAdv(int advId) {
    int ret = BT_RET_OK;
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("advId: %d\r\n", advId);

    ret = hal_ble_stop_advertise();
    if (BT_RET_OK != ret) {
        ret = BT_RET_NG;
        printf("stop ble advertise NG\r\n");
    } else {
        printf("stop ble advertise OK\r\n");
    }

    if(gapcb && gapcb->advEnableCb) {
        gapcb->advDisableCb(advId, ret);
        printf("AdvDisableCallback function call \r\n");
    } else {
        printf("gapcb / gapcb->advEnableCb is NULL\r\n");
    }
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);

    return ret;
}
/* no need to adapter */
int ReadBtMacAddr(unsigned char *mac, unsigned int len)
{
    (void)mac;
    (void)len;
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    // bt_addr_le_t local_pub_addr;
    // bt_addr_le_t local_ram_addr;
    // char le_addr[len];

    // bt_get_local_public_address(&local_pub_addr);
    // bt_addr_le_to_str(&local_pub_addr, le_addr, sizeof(le_addr));
    // printf("Local public addr : %s\r\n", le_addr);

    // bt_get_local_ramdon_address(&local_ram_addr);
    // bt_addr_le_to_str(&local_ram_addr, le_addr, sizeof(le_addr));
    // printf("Local random addr : %s\r\n", le_addr);

    // mac = &le_addr[0];
    printf("No Support to ReadBtMacAddr\r\n");
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
    return BT_RET_NG;
}
/**
 * No Support
 **/
int BleSetSecurityIoCap(BleIoCapMode mode)
{
    int ret = BT_RET_OK;
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("mode:%d\r\n", mode);
    ret = hal_ble_set_sec_iocap(mode);

    if (ret) {
        printf("BleSetSecurityIoCap NG err = %d\r\n", ret);
        printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
        return BT_RET_NG;
    } else {
        printf("BleSetSecurityIoCap OK \r\n");
        printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
        return BT_RET_OK;
    }
}

/**
 * 
 **/
int BleSetSecurityAuthReq(BleAuthReqMode mode) {
    uint8_t authReq = 0;
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("mode:%d\r\n", mode);
    switch(mode)
    {
        case OHOS_BLE_AUTH_NO_BOND:
            authReq = BT_SMP_AUTH_NONE;
        break;
        case OHOS_BLE_AUTH_BOND:
            authReq |= BT_SMP_AUTH_BONDING;
        break;
        case OHOS_BLE_AUTH_REQ_MITM:
            authReq |= BT_SMP_AUTH_MITM;
        break;
        case OHOS_BLE_AUTH_REQ_SC_ONLY:
            authReq |= BT_SMP_AUTH_SC;
        break;
        case OHOS_BLE_AUTH_REQ_SC_BOND:
            authReq |= (BT_SMP_AUTH_SC | BT_SMP_AUTH_BONDING);  
        break;
        case OHOS_BLE_AUTH_REQ_SC_MITM:
            authReq |= (BT_SMP_AUTH_SC | BT_SMP_AUTH_MITM);
        break;
        case OHOS_BLE_AUTH_REQ_SC_MITM_BOND:
            authReq |= (BT_SMP_AUTH_MITM | BT_SMP_AUTH_BONDING);
        break;
        default:
            printf("BleSetSecurityAuthReq BleAuthReqMode err mode = %d\r\n", mode);
            return BT_RET_NG;
    }
    printf("authReq:%d\r\n", authReq);

    hal_ble_set_auth_req(authReq);
    printf("BleSetSecurityAuthReq OK\r\n");
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);

    return BT_RET_OK;
}

/*************************************************************
*Need to adapter interface (GATT interface)
**************************************************************/
int BleGattsDisconnect(int serverId, BdAddr bdAddr, int connId) {
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    (void)(connId);
    (void)(serverId);
    printf("serverId:%d--bdAddr:%s--connId:%d\r\n", serverId, bdAddr.addr, connId);

    if (BT_RET_OK != hal_ble_disconnect(0, bdAddr.addr)) {
        printf("BLE Disconnect NG\r\n");
        return BT_RET_NG;
    } else {
        printf("BLE Disconnect OK\r\n");
        return BT_RET_OK;
    }
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
}

int BleGattsSetEncryption(BdAddr bdAddr, BleSecAct secAct) {
    int ret = BT_RET_OK;

    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("bdAddr:%s--secAct:%d\r\n", bdAddr.addr, secAct);

    if (OHOS_BLE_SEC_NONE == secAct) {
        printf("BT No connection yet, cannot be set, return OK when 0\r\n");
        return BT_RET_OK;
    }
  
    if (BT_RET_OK != hal_ble_select_conn(1, bdAddr.addr)) {
        printf("BLE select connect NG\r\n");
        return BT_RET_NG;
    } else {
        printf("BLE select connect OK\r\n");
    }

    if (secAct == OHOS_BLE_SEC_NONE) {
        ret = hal_ble_security(BT_SECURITY_L1);
    } else if (secAct == OHOS_BLE_SEC_ENCRYPT) {
        ret = hal_ble_security(BT_SECURITY_L2);
    } else if (secAct == OHOS_BLE_SEC_ENCRYPT_NO_MITM) {
        ret = hal_ble_security(BT_SECURITY_L2);
    } else if (secAct == OHOS_BLE_SEC_ENCRYPT_MITM) {
        ret = hal_ble_security(BT_SECURITY_L3);
    }

    if (BT_RET_OK != ret) {
        ret = BT_RET_NG;
        printf("BLE set security NG\r\n");
    } else {
        printf("BLE set security OK\r\n");
    }
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
    
    return ret;
}

/**
 * No Support
 **/
int BleGattSecurityRsp(BdAddr bdAddr, bool accept)
{
    int ret = BT_RET_OK;
    (void)(bdAddr);

    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("bdAddr:%s---accept:%d\r\n", bdAddr.addr, accept);

    if(accept) {
        ret = hal_ble_auth_pairing_confirm();   
        if (BT_RET_OK != ret) {
            ret = BT_RET_NG;
            printf("BleGattSecurityRsp accept NG\r\n");
        } else {
            printf("BleGattSecurityRsp accept OK\r\n");
        }
    } else {
        printf("Upper layer reject security request\r\n");
    }
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
    
    return ret;
}

/**
 *  cannot understand the Use of rawData
 **/
int BleStartAdvEx(int *advId, const StartAdvRawData rawData, BleAdvParams advParam)
{
    int ret = 0;
    //unsigned char i = 0;
    //unsigned char adv_type = 0xff;
    BleConfigAdvData param_data;

    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("*advId = %p\r\n", advId);

    if (START_ADV_ALREADY == startAdvFlag) {
        printf("start advertising already!!!\r\n");
        if (BT_RET_OK != hal_ble_stop_advertise()) {
            printf("stop advertise failed use the last adv\r\n");
            return BT_RET_OK;
        } else {
            printf("stop advertise OK restart the adv\r\n");
            startAdvFlag = START_ADV_NONE;
        }
    }

    memset(&param_data, 0x00, sizeof(param_data));

    param_data.advLength = (unsigned short)rawData.advDataLen;
    param_data.advData = (char *)rawData.advData;
    param_data.scanRspLength = (unsigned short)rawData.rspDataLen;
    param_data.scanRspData = (char *)rawData.rspData;

    printf("advLength:%d---scanRspLength:%d\r\n", param_data.advLength, param_data.scanRspLength);

    ret = hal_ble_start_advertiseEx(0, advParam.advType, 0, advParam.minInterval, advParam.maxInterval, 
                            param_data.advData, param_data.advLength,
                            param_data.scanRspData, param_data.scanRspLength);
    if (BT_RET_OK == ret) {
        startAdvFlag = START_ADV_ALREADY;
        printf("Use BleStartAdv to Implement BleStartAdvEx OK\r\n");
    } else {
        printf("Use BleStartAdv to Implement BleStartAdvEx FAil\r\n");
    }

    if(gapcb && gapcb->advEnableCb) {
        gapcb->advEnableCb(0, ret);
        printf("AdvEnableCallback function call \r\n");
    } else {
        printf("gapcb && gapcb->advEnableCb is NULL\r\n");
    }
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);

    return ret;
}

int svc_cnt = 0;
int attr_cnt = 0;
int charc_vale_cb_cnt = 0;
struct charc_value_cb_t{
    struct bt_uuid *charc_uuid;
    BleGattServiceRead read_cb;
    BleGattServiceWrite write_cb;
};
#define HILINK_ATTR_CNT             (5)
#define HILINK_SERVICE_CNT          (5)
#define HILINK_CHARC_VALUE_CNT      (5)
static struct charc_value_cb_t charc_value_cb[HILINK_CHARC_VALUE_CNT]; 
static struct bt_gatt_attr *oh_attrs[HILINK_ATTR_CNT];
static struct bt_gatt_service oh_svc[HILINK_SERVICE_CNT];

int dm_cnt = 0;
struct svc_dm_release {
    int handle;
    int count;
    void *ptr[10];
};
static struct svc_dm_release dm_rel[HILINK_SERVICE_CNT];
struct attrs_trans_handle {
    int hilink_handle[HILINK_ATTR_CNT];
    int bfl_handle[HILINK_ATTR_CNT];
};
static struct attrs_trans_handle handle_change[HILINK_SERVICE_CNT];

struct bt_uuid *bt_prisvc_uuid = BT_UUID_GATT_PRIMARY;
struct bt_uuid *bt_secsvc_uuid = BT_UUID_GATT_SECONDARY;
struct bt_uuid *bt_chrc_uuid   = BT_UUID_GATT_CHRC;
struct bt_uuid *bt_ccc_uuid    = BT_UUID_GATT_CCC;

static ssize_t charc_value_read(struct bt_conn *conn,
			    const struct bt_gatt_attr *attr,
			    void *buf, u16_t len, u16_t offset)

{
    for(int i = 0; i < HILINK_CHARC_VALUE_CNT; i++)
    {
        if(!bt_uuid_cmp(charc_value_cb[i].charc_uuid, attr->uuid))
        {
            charc_value_cb[i].read_cb((unsigned char *)buf, (unsigned int *)&len);
            printf("%s len = %d,readdata:\r\n", __func__, len);
             for(int j= 0; j< len; j++)
                printf("0x%x",*((unsigned char *)(buf+j)));
            printf("\r\n");
            return len;
        }
    }
    return 0;
}

static ssize_t charc_value_write(struct bt_conn *conn,
					 const struct bt_gatt_attr *attr,
					 const void *buf, u16_t len,
					 u16_t offset, u8_t flags)
{
    for(int i = 0; i < HILINK_CHARC_VALUE_CNT; i++)
    {
        if(!bt_uuid_cmp(charc_value_cb[i].charc_uuid, attr->uuid))
        {
            printf("%s len = %d\r\n",  __func__, len);
            for(int j= 0; j< len; j++)
                printf("0x%x",*((unsigned char *)(buf+j)));
            printf("\r\n");
            charc_value_cb[i].write_cb((unsigned char *)buf, (unsigned int)len);
            return len;
        }
    }    
    return 0;
}
                     
static int setup_oh_service_attr(struct bt_gatt_attr *attr, struct bt_uuid *uuid)
{
    attr->uuid      = bt_prisvc_uuid;
    attr->perm      = BT_GATT_PERM_READ;
    attr->read      = bt_gatt_attr_read_service;
    attr->user_data = (void *)uuid;
    attr->handle = 0;

    dm_rel[svc_cnt].ptr[dm_cnt] = (void *)uuid;
    dm_cnt++;
    
    return 0;
}

static int setup_oh_char_attr(struct bt_gatt_attr *attr, struct bt_uuid *uuid, uint8_t prop)
{
    struct bt_gatt_chrc *chrc = NULL;

    chrc = (struct bt_gatt_chrc *)malloc(sizeof(struct bt_gatt_chrc));
    if (!chrc) {
        printf("%s malloc failed\r\n", __func__);
        return -1;
    }

    chrc->uuid       = uuid;
    chrc->properties = prop;
    chrc->value_handle = 0;

    attr->uuid      = bt_chrc_uuid;
    attr->perm      = BT_GATT_PERM_READ;
    attr->read      = bt_gatt_attr_read_chrc;
    attr->user_data = (void *)chrc;
    attr->handle = 0;

    dm_rel[svc_cnt].ptr[dm_cnt] = (void *)uuid;
    dm_cnt++;
    dm_rel[svc_cnt].ptr[dm_cnt] = (void *)chrc;
    dm_cnt++;

    return 0;
}

static int setup_oh_char_desc_attr(struct bt_gatt_attr *attr, struct bt_uuid *uuid, uint8_t perm,
                                    void *read, void *write, void *userdata)
{
    attr->uuid      = uuid;
    attr->perm      = perm;
    attr->read      = charc_value_read;
    attr->write     = charc_value_write;
    attr->user_data = userdata;
    attr->handle = 0;
    return 0;
}

static int setup_oh_char_ccc_attr(struct bt_gatt_attr *attr, void *cfg_handler)
{
    struct _bt_gatt_ccc *ccc = NULL;

    ccc = (struct _bt_gatt_ccc *)malloc(sizeof(struct _bt_gatt_ccc));
    if (!ccc) {
        printf("%s malloc failed.\r\n", __func__);
        return -1;
    }

    ccc->cfg_changed = cfg_handler;
    ccc->cfg_write = NULL;
    ccc->cfg_match = NULL;

    attr->uuid      = bt_ccc_uuid;
    attr->perm      = BT_GATT_PERM_READ | BT_GATT_PERM_WRITE;
    attr->read      = bt_gatt_attr_read_ccc;
    attr->write     = bt_gatt_attr_write_ccc;
    attr->user_data = (void *)ccc;
    attr->handle = 0;

    dm_rel[svc_cnt].ptr[dm_cnt] = (void *)ccc;
    dm_cnt++;

    return 0;
}

uint8_t get_attr_count(BleGattService *srvcInfo)
{
    uint8_t attr_num = srvcInfo->attrNum;
    BleGattAttr *attr = srvcInfo->attrList;
    uint8_t tlt_cnt = attr_num;
    
    printf("get_attr_count entry attr_num = %d\r\n", attr_num);
    while(attr_num && attr)
    {
        if(attr->attrType == OHOS_BLE_ATTRIB_TYPE_CHAR)
        {
            tlt_cnt++;//for OHOS_BLE_ATTRIB_TYPE_CHAR_VALUE
            if((attr->properties & OHOS_GATT_CHARACTER_PROPERTY_BIT_NOTIFY)
                ||(attr->properties & OHOS_GATT_CHARACTER_PROPERTY_BIT_INDICATE))
            {
                tlt_cnt++;//for OHOS_BLE_ATTRIB_TYPE_CHAR_CLIENT_CONFIG 
            }
        }

        attr_num--;
        attr++;
    }

    return tlt_cnt;
}

uint8_t get_attr_perm(unsigned int permission)
{
    uint8_t attr_perm = BT_GATT_PERM_NONE;
    if(permission & OHOS_GATT_PERMISSION_READ)
        attr_perm |= BT_GATT_PERM_READ;
    if(permission & OHOS_GATT_PERMISSION_READ_ENCRYPTED)
        attr_perm |= BT_GATT_PERM_READ_ENCRYPT;
    if(permission & OHOS_GATT_PERMISSION_READ_ENCRYPTED_MITM)
        attr_perm |= BT_GATT_PERM_READ_AUTHEN;
    if(permission & OHOS_GATT_PERMISSION_WRITE)
        attr_perm |= BT_GATT_PERM_WRITE;
    if(permission & OHOS_GATT_PERMISSION_WRITE_ENCRYPTED)
        attr_perm |= BT_GATT_PERM_WRITE_ENCRYPT;
    if(permission & OHOS_GATT_PERMISSION_WRITE_ENCRYPTED_MITM)
        attr_perm |= BT_GATT_PERM_WRITE_AUTHEN;
    if(permission & OHOS_GATT_PERMISSION_WRITE_SIGNED)
        attr_perm |= BT_GATT_PERM_WRITE_ENCRYPT;
    if(permission & OHOS_GATT_PERMISSION_WRITE_SIGNED_MITM)
        attr_perm |= BT_GATT_PERM_WRITE_ENCRYPT;

    return attr_perm;
}

/**
 * No need to Implement
 **/
int BleGattsStartServiceEx(int *srvcHandle, BleGattService *srvcInfo) {
    int ret = 0;
    int status = OHOS_BT_STATUS_SUCCESS;
    int service_handle = -1;
    uint8_t attr_tlt_cnt = get_attr_count(srvcInfo);
    uint8_t attr_num = srvcInfo->attrNum;
    BleGattAttr *attr = srvcInfo->attrList;
    uint8_t attr_perm;
    uint8_t attr_handle_num = 0;
    int hilink_handle_cnt = 0;
    int ble_handle_cnt = 0;
    uint8_t i;

    unsigned int size = attr_tlt_cnt * sizeof(struct bt_gatt_attr);
    oh_attrs[svc_cnt] = (struct bt_gatt_attr *)malloc(size);

    memset(oh_attrs[svc_cnt], 0, size);
    memset(&oh_svc[svc_cnt], 0, sizeof(struct bt_gatt_service));
    memset(&dm_rel[svc_cnt], 0, sizeof(struct svc_dm_release));
    memset(&handle_change[svc_cnt], 0, sizeof(struct attrs_trans_handle));
    printf("%s attr_tlt_cnt=%d\r\n", __func__, attr_tlt_cnt);

    while(attr_num && attr)
    {
        struct bt_uuid *uuid = NULL;
        uint8_t uuid_len = 0;

        if(attr->uuidType == OHOS_UUID_TYPE_16_BIT)
        {   
            uuid = (struct bt_uuid *)malloc(sizeof(struct bt_uuid_16));
            uuid_len = 2;
        }
        else if(attr->uuidType == OHOS_UUID_TYPE_32_BIT)
        {
            uuid = (struct bt_uuid *)malloc(sizeof(struct bt_uuid_32));
            uuid_len = 4;
        }
        else if(attr->uuidType == OHOS_UUID_TYPE_128_BIT)
         {
            uuid = (struct bt_uuid *)malloc(sizeof(struct bt_uuid_128));
            uuid_len = 16;
         }
         
        bt_uuid_create(uuid, attr->uuid, uuid_len);

        printf("%s attrtype=%d, attproperities=%d\r\n", __func__, attr->attrType, attr->properties);

        if(attr->attrType == OHOS_BLE_ATTRIB_TYPE_SERVICE)
        {
            handle_change[svc_cnt].bfl_handle[attr_handle_num] = ble_handle_cnt;
            handle_change[svc_cnt].hilink_handle[attr_handle_num] = hilink_handle_cnt;
            setup_oh_service_attr(&oh_attrs[svc_cnt][attr_cnt], uuid);
            attr_cnt++;
            attr_handle_num++;
            ble_handle_cnt++;
            hilink_handle_cnt++;
        }
        else if(attr->attrType == OHOS_BLE_ATTRIB_TYPE_CHAR)
        {
            handle_change[svc_cnt].bfl_handle[attr_handle_num] = ble_handle_cnt;
            handle_change[svc_cnt].hilink_handle[attr_handle_num] = hilink_handle_cnt;
            attr_perm = get_attr_perm(attr->permission);
            printf("%s attr->permission=%d, attr_perm=%d, writefun=%p, readfun=%p\r\n", __func__, (int)(attr->permission), attr_perm, attr->func.write, attr->func.read);
            setup_oh_char_attr(&oh_attrs[svc_cnt][attr_cnt], uuid, attr->properties);
            attr_cnt++;

            charc_value_cb[charc_vale_cb_cnt].charc_uuid = uuid;
            charc_value_cb[charc_vale_cb_cnt].read_cb = attr->func.read;
            charc_value_cb[charc_vale_cb_cnt].write_cb = attr->func.write;
            setup_oh_char_desc_attr(&oh_attrs[svc_cnt][attr_cnt], uuid, attr_perm, 
                    NULL, NULL, attr->value);
            charc_vale_cb_cnt++;
            
            attr_cnt++;
            if((attr->properties & OHOS_GATT_CHARACTER_PROPERTY_BIT_NOTIFY)
                ||(attr->properties & OHOS_GATT_CHARACTER_PROPERTY_BIT_INDICATE))
            {
                setup_oh_char_ccc_attr(&oh_attrs[svc_cnt][attr_cnt], NULL);
                attr_cnt++;
            }
            attr_handle_num++;
            ble_handle_cnt += 2;
            hilink_handle_cnt++;
        }

        attr_num--;
        attr++;              
    }
    
    oh_svc[svc_cnt].attrs      = oh_attrs[svc_cnt];
    oh_svc[svc_cnt].attr_count = attr_cnt;
    printf("%s this service'sattr_cnt =%d\r\n", __func__, attr_cnt);
    
    ret = bt_gatt_service_register(&oh_svc[svc_cnt]);
    if (ret) {
        status = OHOS_BT_STATUS_FAIL;
        printf("BleGattsStartServiceEx. fail. \r\n");
    } 
    else
    {
        service_handle = oh_svc[svc_cnt].attrs[0].handle;
        printf("BleGattsStartServiceEx. success. attr count: %d, service id: %d, service handle: %d \r\n", 
            attr_cnt, svc_cnt, service_handle);
        for (i = 0; i < attr_handle_num; i++) {
            handle_change[svc_cnt].bfl_handle[i] += service_handle;
            handle_change[svc_cnt].hilink_handle[i] += service_handle;
            printf("BleGattsStartServiceEx change handle_change[svc_cnt].bfl_handle[%d] = %ld \r\n", i, (long)(handle_change[svc_cnt].bfl_handle[i]));
            printf("BleGattsStartServiceEx change handle_change[svc_cnt].hilink_handle[%d] = %ld \r\n", i, (long)(handle_change[svc_cnt].hilink_handle[i]));
        }
    }

    
    if(gattscb && gattscb->serviceStartCb)
    {
        (gattscb->serviceStartCb)(status, svc_cnt, service_handle);
    }

    dm_rel[svc_cnt].handle = service_handle;
    dm_rel[svc_cnt].count = dm_cnt;
    dm_cnt = 0;

    *srvcHandle = service_handle;
    attr_cnt = 0;
    svc_cnt += 1;
 
    return ret;
}

/**
 * No need to Implement
 **/
int BleGattsStopServiceEx(int srvcHandle) {
    int svc_id = 0;
    int ret = 0;
    int status = OHOS_BT_STATUS_SUCCESS;
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("srvcHandle:%d\r\n", srvcHandle);

    while(svc_id < HILINK_SERVICE_CNT)
    {
        if(dm_rel[svc_id].handle == srvcHandle)
        {
            break;
        }
        svc_id++;
    }

    ret = bt_gatt_service_unregister(&oh_svc[svc_id]);

    for(int i = 0; i < dm_rel[svc_id].count; i++)
    {
        free(dm_rel[svc_id].ptr[i]);
    }
    free(oh_attrs[svc_id]);
    
    if (ret) {
        printf("BleGattsStopServiceEx fail. \n");
        status = OHOS_BT_STATUS_FAIL;
    } else {
        printf("BleGattsStopServiceEx success. \n");
    }

    if(gattscb && gattscb->serviceStopCb) {
        (gattscb->serviceStopCb)(status, svc_id, srvcHandle);
        printf("ServiceStopCallback function call \r\n");
    } else {
        printf("gattscb && gattscb->serviceStopCb is NULL \r\n");
    }
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
    
    return ret;
}

/**
 * use the interface bt_conn_cb_register but the callback cannnot match
 **/
int BleGattsRegisterCallbacks(BtGattServerCallbacks *func) {
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("func:%p\r\n", func);
    gattscb = func;
    printf("BleGattsRegisterCallbacks OK\r\n");
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
    return BT_RET_OK;
}

/**
 * use the interface bt_conn_cb_register but the callback cannnot match
 **/
int BleGattRegisterCallbacks(BtGattCallbacks *func) {
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    printf("func:%p\r\n", func);
    gapcb = func;
    printf("BleGattRegisterCallbacks OK\r\n");
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
    return BT_RET_OK;
}

/**
 * use the interface ble_tp_recv_rd/ble_tp_recv_wr but the parameter cannot match it
 **/
int BleGattsSendResponse(int serverId, GattsSendRspParam *param) {
    (void)(serverId);
    (void)(param);
    printf("BleGattsSendResponse No Support!!! \r\n");
    return BT_RET_NG;
}

/**
 * use the interface bl_tp_send_indicate but the parameter cannot match it
 **/
int BleGattsSendIndication(int serverId, GattsSendIndParam *param) {
    (void)(serverId);
    int ret = 0;
    int status = BT_RET_OK;
    uint8_t i, j;
    int changed_attrHandle = 0;
    printf("%s---%d--- Entry!!! \r\n", __FUNCTION__, __LINE__);
    if (NULL == param) {
        return -1;
    }
    printf("serverId:%d--param:%p,attrhandle=%d,valueLen=%d\r\n", serverId, param, param->attrHandle, param->valueLen);

    #if 1
    for(int i = 0; i< param->valueLen;i++)
        printf("0x%x ",(uint8_t)param->value[i]);
    printf("\r\n");
    #endif

    for (i = 0; i < HILINK_SERVICE_CNT; i++) {
        for (j = 0; j < HILINK_ATTR_CNT; j++) {
            if (handle_change[i].hilink_handle[j] == param->attrHandle) {
                changed_attrHandle = handle_change[i].bfl_handle[j];
                break;
            }
        }
    }
    printf("BleGattsSendIndication param changed_attrHandle = %d\r\n", changed_attrHandle);

    if(indicate_env.ind_state == HAL_GATT_IND_IDLE)
    {
        if(param->confirm) 
        {
            ret = hal_ble_send_indicate(NULL, changed_attrHandle, param->value, param->valueLen);
        }
        else
        {
            ret = hal_ble_send_notify(NULL, changed_attrHandle, param->value, param->valueLen);
        }

        if(!ret)
            indicate_env.ind_state = HAL_GATT_IND_BUSY;
    }
    else
    {
        ret = ble_push_indicate_info(serverId, param);
    }

    if (ret) {
        printf("BleGattsSendIndication fail. \n");
        status = BT_RET_NG;
    } else {
        printf("BleGattsSendIndication success. \n");
    }
 
    printf("%s---%d--- Exit!!! \r\n", __FUNCTION__, __LINE__);
    
    return ret;
}


#if 0

int attr_count = 0;
struct bt_gatt_service prov_svc;
struct bt_gatt_attr *srv_attr;

int BleGattsRegister(BtUuid appUuid) {
    return BT_RET_OK;
}

int BleGattsUnRegister(int serverId) {
     return BT_RET_OK;
}

int BleGattsAddService(int serverId, BtUuid srvcUuid, bool isPrimary, int number) {
     (void ) serverId;
    
    srv_attr = malloc(sizeof(struct bt_gatt_attr) * number);
    
    struct bt_gatt_attr * attr = (struct bt_gatt_attr *)malloc(sizeof(struct bt_gatt_attr));

    if (isPrimary) {
        attr->uuid = bt_prisvc_uuid;
    } else {
        attr->uuid = bt_secsvc_uuid;
    }
    
    attr->read = bt_gatt_attr_read_service;
    attr->write = NULL;
    
    attr->user_data = malloc(srvcUuid.uuidLen);
    memcpy(attr->user_data, srvcUuid.uuid, srvcUuid.uuidLen);

    attr->handle = 0;
    attr->perm = BT_GATT_PERM_READ;

    memcpy(srv_attr, attr, sizeof(struct bt_gatt_attr));

    attr_count += 1;
    
    return BT_RET_OK;
}

int BleGattsDeleteService(int serverId, int srvcHandle) {
    (void)(srvcHandle);
    return BT_RET_OK;
}

int BleGattsAddCharacteristic(int serverId, int srvcHandle, BtUuid characUuid, int properties, int permissions) {
    (void) serverId;
    (void) srvcHandle;

    struct bt_gatt_attr * char_dec = (struct bt_gatt_attr *)malloc(sizeof(struct bt_gatt_attr));
    {
        char_dec->uuid = bt_chrc_uuid;
        char_dec->read = bt_gatt_attr_read_chrc;
        char_dec->write = NULL;

        struct bt_gatt_chrc *char_dec_val = (struct bt_gatt_chrc *)malloc(sizeof(struct bt_gatt_chrc));
        char_dec_val->uuid = malloc(characUuid.uuidLen);
        memcpy(char_dec_val->uuid, characUuid.uuid, characUuid.uuidLen);
        char_dec_val->value_handle = 0;
        char_dec_val->properties = properties;

        char_dec->user_data =  (struct bt_gatt_chrc *)malloc(sizeof(struct bt_gatt_chrc));
        memcpy(char_dec->user_data, char_dec_val, sizeof(struct bt_gatt_chrc));
        free(char_dec_val);

        char_dec->handle = 0;
        char_dec->perm = BT_GATT_PERM_READ;
    }
    memcpy(srv_attr + attr_count, char_dec, sizeof(struct bt_gatt_attr));
    attr_count += 1;

    struct bt_gatt_attr * char_val = (struct bt_gatt_attr *)malloc(sizeof(struct bt_gatt_attr));
    {
        char_val->uuid = malloc(characUuid.uuidLen);
        memcpy(char_val->uuid, characUuid.uuid, characUuid.uuidLen);
        char_val->read = NULL;
        char_val->write = NULL;
        char_val->user_data = NULL;
        char_val->handle = 0;
        char_val->perm = permissions;
    }
    memcpy(srv_attr + attr_count, char_val, sizeof(struct bt_gatt_attr));
    attr_count += 1;

    return BT_RET_OK;
}


int BleGattsAddDescriptor(int serverId, int srvcHandle, BtUuid descUuid, int permissions) {
    (void) serverId;
    (void) srvcHandle;
    
    struct bt_gatt_attr * desc_attr = (struct bt_gatt_attr *)malloc(sizeof(struct bt_gatt_attr));
    {
        desc_attr->uuid = malloc(descUuid.uuidLen);
        memcpy(desc_attr->uuid, descUuid.uuid, descUuid.uuidLen);
        desc_attr->read = NULL;
        desc_attr->write = NULL;
        desc_attr->user_data = NULL;
        desc_attr->handle = 0;
        desc_attr->perm = permissions;
    }
    memcpy(srv_attr + attr_count, desc_attr, sizeof(struct bt_gatt_attr));
    attr_count += 1;
    
    return BT_RET_OK;
}

/**
 * No need to Implement
 **/
int BleGattsStartService(int serverId, int srvcHandle) {
    (void) serverId;
    (void) srvcHandle;
    
    int ret = 0;
    
    prov_svc.attrs = srv_attr;
    prov_svc.attr_count = attr_count;
    ret = bt_gatt_service_register(&prov_svc);

    if (ret) {
        printf("BLE GATT Add Service NG. attr_count: %d. \n", attr_count);
    } else {
        printf("BLE GATT Add Service OK, attr_count: %d. \n", attr_count);
    }

    return ret;
}

/**
 * No need to Implement
 **/
int BleGattsStopService(int serverId, int srvcHandle) {
    (void)(serverId);
    (void)(srvcHandle);
    printf("No Support to stop gatt server\r\n");
    return BT_RET_NG;
}

#endif

/************************************************************
* NO need to adapter interface ohos_bt_gatt_client.h
***********************************************************/
int BleGattcRegister(BtUuid appUuid) {
    (void)(appUuid);
    printf("No Support to register gatt client\r\n");
    return BT_RET_NG;
}

int BleGattcUnRegister(int clientId) {
    (void)(clientId);
    printf("No Support to register gatt client\r\n");
    return BT_RET_NG;
}

int BleGattcConnect(int clientId, const BdAddr *bdAddr, bool isDirect, int transport)
{
    (void)(clientId);
    (void)(bdAddr);
    (void)(isDirect);
    (void)(transport);

    printf("No Support BleGattcConnect\r\n");
    return BT_RET_NG;
}

int BleGattcDisconnect(int clientId, const BdAddr *bdAddr, int connId)
{
    (void)(clientId);
    (void)(bdAddr);
    (void)(connId);

    printf("No Support BleGattcDisconnect\r\n");
    return BT_RET_NG;
}

int BleGattcConnectParaUpdate(const BdAddr *bdAddr, BtGattcConnPara connPara)
{
    (void)(bdAddr);
    (void)(connPara);

    printf("No Support BleGattcConnectParaUpdate\r\n");
    return BT_RET_NG;
}

int BleGattcSearchServices(int connId, BtUuid filterUuid)
{
    (void)(connId);
    (void)(filterUuid);
    printf("No Support BleGattcSearchServices\r\n");
    return BT_RET_NG;
}

int BleGattcReadCharacteristic(int connId, int handle)
{
    (void)(connId);
    (void)(handle);
    printf("No Support BleGattcReadCharacteristic\r\n");
    return BT_RET_NG;
}

int BleGattcWriteCharacteristic(int connId, int handle, int writeType, int len, char *value)
{
    (void)(connId);
    (void)(handle);
    (void)(writeType);
    (void)(len);
    (void)(value);
    printf("No Support BleGattcWriteCharacteristic\r\n");
    return BT_RET_NG;
}

int BleGattcReadDescriptor(int connId, int handle)
{
    (void)(connId);
    (void)(handle);
    printf("No Support BleGattcReadDescriptor\r\n");
    return BT_RET_NG;
}

int BleGattcWriteDescriptor(int connId, int handle, int writeType, int len, char *value)
{
    (void)(connId);
    (void)(handle);
    (void)(writeType);
    (void)(len);
    (void)(value);
    printf("No Support BleGattcWriteDescriptor\r\n");
    return BT_RET_NG;
}

int BleGattcExecuteWrite(int connId, int execute)
{
    (void)(connId);
    (void)(execute);
    printf("No Support BleGattcExecuteWrite\r\n");
    return BT_RET_NG;
}

int BleGattcConfigureMtuSize(int connId, int mtuSize)
{
    (void)(connId);
    (void)(mtuSize);
    printf("No Support BleGattcConfigureMtuSize\r\n");
    return BT_RET_NG;
}

int BleGattcReadRemoteRssi(int clientId, const BdAddr *bdAddr)
{
    (void)(clientId);
    (void)(bdAddr);
    printf("No Support BleGattcReadRemoteRssi\r\n");
    return BT_RET_NG;
}

int BleGattcRegisterNotifications(int clientId, const BdAddr *bdAddr, int handle, int enable)
{
    (void)(clientId);
    (void)(bdAddr);
    (void)(handle);
    (void)(enable);

    printf("No Support BleGattcRegisterNotifications\r\n");
    return BT_RET_NG;
}

int BleGattcRegisterCallbacks(BtGattClientCallbacks *func) {
    (void)(func);
    printf("No Support to register callback for client\r\n");
    return BT_RET_NG;
}

/************************************************************
* NO need to adapter interface ohos_bt_gatt.h
***********************************************************/
int BleScanFilterParamSetup(BleAdvScanFilterParam *param)
{
    (void)(param);
    printf("No Support BleScanFilterParamSetup\r\n");
    return BT_RET_NG;
}

int BleScanFilterAddRemove(BleAdvScanFilterCondition *param)
{
    (void)(param);
    printf("No Support BleScanFilterAddRemove\r\n");
    return BT_RET_NG;
}

int BleScanFilterClear(int clientId, int filterIndex)
{
    (void)(clientId);
    (void)(filterIndex);
    printf("No Support BleScanFilterClear\r\n");
    return BT_RET_NG;
}

int BleScanFilterEnable(int clientId, bool enable)
{
    (void)(clientId);
    (void)(enable);
    printf("No Support BleScanFilterEnable\r\n");
    return BT_RET_NG;
}

int BleSetScanParameters(int clientId, BleScanParams *param)
{
    (void)(clientId);
    (void)(param);
    printf("No Support BleSetScanParameters\r\n");
    return BT_RET_NG;
}

int BleStartScan(void)
{
    printf("No Support BleStartScan\r\n");
    return BT_RET_NG;
}

int BleStopScan(void)
{
    printf("No Support BleStopScan\r\n");
    return BT_RET_NG;
}

int BleUpdateAdv(int advId, const BleAdvParams *param)
{
    (void)(advId);
    (void)(param);
    printf("No Support BleUpdateAdv\r\n");
    return BT_RET_NG;
}
/************************************************************
* NO need to adapter interface ohos_bt_gatt_server.h
************************************************************/
int BleGattsClearServices(int serverId)
{
    (void)(serverId);

    printf("No Support BleGattsClearServices\r\n");
    return BT_RET_NG;
}
